package cn.source.framework.interceptor.impl;

import cn.source.common.core.domain.BaseEntity;
import cn.source.common.core.domain.entity.SysUser;
import cn.source.common.utils.DateUtils;
import cn.source.common.utils.SecurityUtils;
import cn.source.common.utils.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

/**
 * @Description: 自定义拦截器，注入创建人，创建日期，修改人，修改日期，企业id
 *
 * @author: sourcebyte.vip
 * @date: 2023年10月18日 14:33
 */
@Intercepts({
    @Signature(
            type = Executor.class,
            method = "update",
            args = {MappedStatement.class, Object.class}),
})
public class HandleBaseInfoInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement mappedStatement = (MappedStatement) args[0];
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        // 用户类不处理，会导致获取不到用户信息出错
        if (args[1] instanceof SysUser) {
            return invocation.proceed();
        }
        if (args[1] instanceof BaseEntity) {
            BaseEntity baseEntity = (BaseEntity) args[1];
            if (sqlCommandType == SqlCommandType.UPDATE) {
                baseEntity.setUpdateTime(DateUtils.getNowDate());
                baseEntity.setUpdateBy(SecurityUtils.getUsername());
            } else if (sqlCommandType == SqlCommandType.INSERT) {
                baseEntity.setCreateTime(DateUtils.getNowDate());
                baseEntity.setCreateBy(SecurityUtils.getUsername());
                if (StringUtils.isNull(baseEntity.getCompanyId())
                        && StringUtils.isNotNull(
                                SecurityUtils.getLoginUser().getUser().getCompanyId())) {
                    baseEntity.setCompanyId(SecurityUtils.getLoginUser().getUser().getCompanyId());
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {}
}
